
import 'package:valovault_reminder/common/ui/val_auto_fit_screen_size.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'val_ui_kit_btn.dart';
import 'val_ui_kit_fast_element.dart';
import 'val_fast_string_tool.dart';
import 'val_common_text.dart';

class ValUIKitDialog {
  static final Set<String> _showOnce = {};
  static const String tagProgress = "tagProgress";
  static int _count = 0;

  static void showProgress(BuildContext context, {bool? barrierDismissible, ValueNotifier<double>? progress}) {
    if (_showOnce.contains(tagProgress)) return;
    showCenter(
      context,
      CenterProgress(progress: progress),
      barrierDismissible: barrierDismissible ?? true,
      tag: tagProgress,
      barrierColor: const Color(0x00000000),
    );
  }

  static void hideProgress(BuildContext context) {
    if (!_showOnce.contains(tagProgress)) return;
    _showOnce.remove(tagProgress);
    closeDialog(context);
  }

  ///关闭对话框
  static void closeDialog(BuildContext context) {
    if (_count <= 0) return;
    _count--;
    if (Navigator.of(context).canPop()) Navigator.of(context).pop();
  }

  ///中间动画
  static Future<R?> showCenter<R>(
      BuildContext context,
      Widget dialogContent, {
        bool barrierDismissible = false,
        Color barrierColor = Colors.black54,
        Duration? transitionDuration,
        RouteTransitionsBuilder? transitionBuilder,
        String? tag,
      }) {
    return show<R>(
      context,
      dialogContent,
      transitionBuilder ?? DialogAnimUtils.centerAnim,
      barrierDismissible: barrierDismissible,
      barrierColor: barrierColor,
      transitionDuration: transitionDuration ?? const Duration(milliseconds: 250),
      tag: tag,
    );
  }

  ///显示一个Dialog，[barrierDismissible]物理返回按键是否可关闭，默认不关闭。
  ///
  ///[tag]设置tag后，则该tag类型的dialog同一时间只会显示一个，不会堆叠。
  static Future<R?> show<R>(
      BuildContext context,
      Widget dialogContent,
      RouteTransitionsBuilder? transitionBuilder, {
        bool barrierDismissible = false,
        Color barrierColor = Colors.black54,
        Duration transitionDuration = const Duration(milliseconds: 250),
        String? tag,
      }) {
    _count++;
    hideProgress(context);
    if (ValFastStringTool.isNotEmpty(tag) && _showOnce.contains(tag)) return Future.value();
    if (ValFastStringTool.isNotEmpty(tag)) _showOnce.add(tag!);
    return Navigator.of(context, rootNavigator: true).push<R>(RawDialogRoute<R>(
      pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
        CapturedThemes themes = InheritedTheme.capture(
          from: context,
          to: Navigator.of(
            context,
            rootNavigator: true,
          ).context,
        );

        var child = WillPopScope(
          child: dialogContent,
          onWillPop: () async => barrierDismissible,
        );

        return themes.wrap(child);
      },
      barrierDismissible: barrierDismissible,
      barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
      barrierColor: barrierColor,
      transitionDuration: transitionDuration,
      transitionBuilder: transitionBuilder,
    ))
      ..whenComplete(() {
        if (ValFastStringTool.isNotEmpty(tag)) _showOnce.remove(tag!);
      });
  }
}

///dialog的动画
class DialogAnimUtils {
  static Widget centerAnim(
      BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
    return ScaleTransition(
      scale: Tween(begin: 0.0, end: 1.0).animate(
        CurvedAnimation(parent: animation, curve: Curves.fastOutSlowIn),
      ),
      child: child,
    );
  }

  static Widget bottomAnim(
      BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
    return SlideTransition(
      position: Tween<Offset>(begin: const Offset(0.0, 1.0), end: const Offset(0.0, 0.0)).animate(
        CurvedAnimation(parent: animation, curve: Curves.fastOutSlowIn),
      ),
      child: child,
    );
  }

  static Widget rightTopAnim(
      BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
    return ScaleTransition(
      alignment:Alignment.topRight,
      scale: Tween<double>(begin: 0.01, end: 1).animate(CurvedAnimation(parent: animation, curve: Curves.fastOutSlowIn),),
      child: child,
    );

  }
}

///滚轮选择器
class WheelPickDialog extends StatelessWidget {
  const WheelPickDialog(
      this.child,
      this.onBack,
      this.onConfirm, {
        Key? key,
        this.height = 244,
        this.cancelStr = '取消',
        this.title,
        this.titleFontSize = 16,
        this.btnFontSize = 15,
        this.confirmStr = '确定',
        this.btnConfirmColor,
        this.topPadding,
      }) : super(key: key);
  final double height;
  final String? title;
  final Color? btnConfirmColor;
  final Widget child;
  final String cancelStr;
  final String confirmStr;
  final double titleFontSize;
  final double btnFontSize;
  final EdgeInsetsGeometry? topPadding;
  final VoidCallback onBack;
  final VoidCallback onConfirm;

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: Alignment.bottomCenter,
      child: Material(
        child: SizedBox(
          height: height.w,
          child: Column(
            children: [
              Padding(
                padding: topPadding ?? EdgeInsets.fromLTRB(11.w, 11.w, 0, 11.w),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    CommonRootAction(
                      onBack,
                      text: ValCommonText.oneLine(
                        cancelStr,
                        btnFontSize,
                        const Color(0xFF9C9C9C),
                      ),
                    ),
                    if (ValFastStringTool.isNotEmpty(title))
                      ValCommonText.oneLine(
                        title!,
                        titleFontSize,
                        const Color(0xFF333333),
                      ),
                    CommonRootAction(
                      onConfirm,
                      text: ValCommonText.oneLine(
                        confirmStr,
                        btnFontSize,
                        btnConfirmColor ?? const Color(0xFF0FBB86),
                      ),
                    ),
                  ],
                ),
              ),
              Container(height: 0.5.w, color: const Color(0xFFEFEFEF)),
              Expanded(child: child),
            ],
          ),
        ),
      ),
    );
  }
}

class WheelPickUtils {
  ///单轮子
  static Widget getOne<T>(
      List<T> data,
      ValueChanged<int> onSelectedItemChanged, {
        NullableIndexedWidgetBuilder? itemBuilder,
        Widget selectionOverlay = const CupertinoPickerDefaultSelectionOverlay(),
        String Function(T)? getValue,
        FixedExtentScrollController? scrollController,
      }) {
    return CupertinoPicker.builder(
      key: UniqueKey(),
      itemExtent: 40.w,
      onSelectedItemChanged: onSelectedItemChanged,
      itemBuilder: itemBuilder ?? (c, i) => content(data[i], getValue: getValue),
      childCount: data.length,
      selectionOverlay: selectionOverlay,
      scrollController: scrollController,
    );
  }

  ///双轮子
  static Widget getTwo<T, T1>(
      List<T> data,
      List<List<T1>> data1,
      Function(int, int) result, {
        String Function(T)? getValueOne,
        String Function(T1)? getValueTwo,
        FixedExtentScrollController? scrollControllerOne,
        FixedExtentScrollController? scrollControllerTwo,
      }) {
    ValueNotifier<int> oneSelect = ValueNotifier(scrollControllerOne?.initialItem ?? 0);
    bool first = true;
    return Row(
      children: [
        Expanded(
          child: getOne(
            data,
                (index) {
              oneSelect.value = index;
              result(index, 0);
            },
            selectionOverlay: const CupertinoPickerDefaultSelectionOverlay(capEndEdge: false),
            getValue: getValueOne,
            scrollController: scrollControllerOne,
          ),
        ),
        Expanded(
          child: ValueListenableBuilder<int>(
            valueListenable: oneSelect,
            builder: (BuildContext context, value, Widget? child) {
              if (first) {
                first = false;
              } else {
                scrollControllerTwo = FixedExtentScrollController(initialItem: 0);
              }
              return getOne(
                data1[value],
                    (index) {
                  result(oneSelect.value, index);
                },
                selectionOverlay: const CupertinoPickerDefaultSelectionOverlay(capStartEdge: false),
                getValue: getValueTwo,
                scrollController: scrollControllerTwo,
              );
            },
          ),
        )
      ],
    );
  }

  ///双轮子 - 两列数据互相独立，不关联
  static Widget getTwoNoRelation<T, T1>(
      List<T> data,
      List<T1> data1,
      Function(int, int) result, {
        String Function(T)? getValueOne,
        String Function(T1)? getValueTwo,
        Widget? getOneTitle,
        Widget? getTwoTitle,
        FixedExtentScrollController? scrollControllerOne,
        FixedExtentScrollController? scrollControllerTwo,
      }) {
    int dataIndex = scrollControllerOne?.initialItem ?? 0;
    int dataIndex1 = scrollControllerTwo?.initialItem ?? 0;

    bool hasTitleWidget = getOneTitle != null || getTwoTitle != null;

    ///构建轮子
    Widget buildWheel() {
      return Row(
        children: [
          Expanded(
            child: getOne(
              data,
                  (index) {
                dataIndex = index;
                result(dataIndex, dataIndex1);
              },
              selectionOverlay: const CupertinoPickerDefaultSelectionOverlay(capEndEdge: false),
              getValue: getValueOne,
              scrollController: scrollControllerOne,
            ),
          ),
          Expanded(
            child: getOne(
              data1,
                  (index) {
                dataIndex1 = index;
                result(dataIndex, dataIndex1);
              },
              selectionOverlay: const CupertinoPickerDefaultSelectionOverlay(capEndEdge: false),
              getValue: getValueTwo,
              scrollController: scrollControllerTwo,
            ),
          ),
        ],
      );
    }

    return hasTitleWidget
        ? Column(
      children: [
        Padding(
          padding: EdgeInsets.only(top: 15.w),
          child: Row(
            children: [
              Expanded(child: Center(child: getOneTitle ?? Container())),
              Expanded(child: Center(child: getTwoTitle ?? Container())),
            ],
          ),
        ),
        Expanded(child: buildWheel()),
      ],
    )
        : buildWheel();
  }

  ///显示内容
  static Widget content<T>(
      T value, {
        String Function(T)? getValue,
        double fontSize = 16,
        Color fontColor = const Color(0xFF333333),
      }) {
    String v = '$value';
    if (getValue != null) v = getValue(value);
    return Center(child: ValCommonText.oneLine(v, fontSize, fontColor));
  }

  ///双轮子-自定义数据
  static Widget getTwoCustom<T, T1>({
    required List<T> dataOne,
    required List<T1> Function(int) getDataTwo,
    required Function(int, int) result,
    String Function(T)? getValueOne,
    String Function(T1)? getValueTwo,
    Widget? getOneTitle,
    Widget? getTwoTitle,
    FixedExtentScrollController? scrollControllerOne,
    FixedExtentScrollController? scrollControllerTwo,
  }) {
    ValueNotifier<int> oneSelect = ValueNotifier(scrollControllerOne?.initialItem ?? 0);
    bool first = true;
    bool hasTitleWidget = getOneTitle != null || getTwoTitle != null;

    Widget child = Row(
      children: [
        Expanded(
          child: getOne(
            dataOne,
                (index) {
              oneSelect.value = index;
              result(index, 0);
            },
            selectionOverlay: const CupertinoPickerDefaultSelectionOverlay(capEndEdge: false),
            getValue: getValueOne,
            scrollController: scrollControllerOne,
          ),
        ),
        Expanded(
          child: ValueListenableBuilder<int>(
            valueListenable: oneSelect,
            builder: (BuildContext context, value, Widget? child) {
              if (first) {
                first = false;
              } else {
                scrollControllerTwo = FixedExtentScrollController(initialItem: 0);
              }
              return getOne(
                getDataTwo(value),
                    (index) {
                  result(value, index);
                },
                selectionOverlay: const CupertinoPickerDefaultSelectionOverlay(capStartEdge: false),
                getValue: getValueTwo,
                scrollController: scrollControllerTwo,
              );
            },
          ),
        )
      ],
    );

    if (hasTitleWidget) {
      child = Column(
        children: [
          Padding(
            padding: EdgeInsets.only(top: 15.w),
            child: Row(
              children: [
                Expanded(child: Center(child: getOneTitle ?? Container())),
                Expanded(child: Center(child: getTwoTitle ?? Container())),
              ],
            ),
          ),
          Expanded(child: child),
        ],
      );
    }

    return child;
  }
}

///顶部的操作按钮
class CommonRootAction extends StatelessWidget {
  const CommonRootAction(
      this.tap, {
        Key? key,
        this.img,
        this.text,
        this.backColor,
        this.size,
        this.hasInkWell = true,
        this.rightPadding,
        this.leftPadding,
        this.contentPadding,
      }) : super(key: key);

  final String? img;
  final Widget? text;
  final Function() tap;
  final Color? backColor;
  final double? size;
  final bool hasInkWell;
  final double? rightPadding;
  final double? leftPadding;
  final EdgeInsets? contentPadding;

  @override
  Widget build(BuildContext context) {
    Widget child = Container();
    child = text!;

    return UnconstrainedBox(
      child: Padding(
          padding: EdgeInsets.only(right: rightPadding ?? 11.w, left: leftPadding ?? 0.w),
          child: ValUIKitBtn(
            child,
            tap,
            padding: contentPadding ?? EdgeInsets.all(5.w),
            hasInkWell: hasInkWell,
          )),
    );
  }
}